package stdx;

import java.io.*;
import java.util.*;

public class ConfigFile implements Closeable{
	class Data{
		public String key = "";
		public String val = "";
		public String info = "";

		public Data(String key, String val){
			this(key, val, "");
		}
		public Data(String key, String val, String info){
			this.key = key;
			this.val = val;
			this.info = info;
		}
	}

	String filepath = null;
	ArrayList<Data> vec = new ArrayList<Data>();

	public ConfigFile(){
	}
	public ConfigFile(String path) throws IOException, FileNotFoundException{
		open(path);
	}

	public void close(){
		vec.clear();
	}
	public void save() throws IOException, FileNotFoundException{
		save(filepath);
	}
	public boolean reload() throws IOException, FileNotFoundException{
		return open(filepath);
	}
	public void save(String path) throws IOException, FileNotFoundException{
		Utils.SetFileContent(path, toString().getBytes());
	}
	public boolean open(String path) throws IOException, FileNotFoundException{
		String content = Utils.GetFileString(path);

		close();

		int pos = 0;
		String msg = "";
		String key = "";
		String val = "";
		String[] arr = content.split("\n");

		for (String str : arr){
			if (str.length() < 2 || str.charAt(0) == '#' || (str.charAt(0) == '-' && str.charAt(1) == '-')){
				msg += str + "\n";
				continue;
			}

			if ((pos = str.indexOf("=")) < 0){
				msg += str + "\n";
				continue;
			}

			if ((key = str.substring(0, pos).trim()).isEmpty()){
				msg += str + "\n";
				continue;
			}

			val = str.substring(pos + 1).trim();

			vec.add(new Data(key, val, msg));

			msg = "";
		}

		filepath = path;

		return vec.size() > 0;
	}

	public String toString(){
		String str = "";
		String tag = Utils.IsLinux() ? "\n" : "\r\n";

		for (Data item : vec){
			str += item.info;
			str += item.key + " = ";
			str += item.val + tag;
		}

		return str;
	}
	public String get(String name){
		int len = -1;
		String val = "";

		for (Data item : vec){
			if (name.equals(item.key)){
				val = item.val;
				len = val.length();

				if (len > 1 && ((val.charAt(0) == '\'' && val.charAt(len - 1) == '\'') || (val.charAt(0) == '\"' && val.charAt(len - 1) == '\"'))){
					val = val.substring(1, len - 1);
				}

				break;
			}
		}

		if (len < 0) return val;

		if (val.isEmpty()) return val;

		return Utils.Translate(val);
	}
	public int getInt(String name){
		int val = 0;
		String str = get(name);

		if (Utils.IsEmpty(str)) return val;
		
		try{
			val = Integer.parseInt(str);
		}
		catch(Exception e){
		    e.printStackTrace();
		}

		return val;
	}
	public double getDoule(String name){
		double val = 0;
		String str = get(name);

		if (Utils.IsEmpty(str)) return val;

		try{
			val = Double.parseDouble(str);
		}
		catch(Exception e){
            e.printStackTrace();
		}

		return val;
	}
	public boolean set(String name, String data){
		String val = data.replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t");

		for (Data item : vec){
			if (name.equals(item.key)){
				String str = item.val;

				if (str.isEmpty()){
					if (Utils.IsAmountString(val)){
						str = val;
					}
					else{
						str = "\"" + val + "\"";
					}
				}
				else if (str.charAt(0) == '\'' || str.charAt(0) == '\"'){
					str = "\"" + val + "\"";
				}
				else{
					str = val;
				}

				return true;
			}
		}

		if (Utils.IsAmountString(val)){
			vec.add(new Data(name, val));
		}
		else{
			vec.add(new Data(name, "\"" + val + "\""));
		}

		return true;
	}
	public void set(String name, Object val){
		set(name, String.valueOf(val));
	}
	public void set(String name, boolean val){
		set(name, val ? "true" : "false");
	}
	public HashMap<String, String> getMapData(){
		int len;
		String val;
		HashMap<String, String> map = new HashMap<String, String>();

		for (Data item : vec){
			val = item.val;
			len = val.length();

			if (len > 1 && ((val.charAt(0) == '\'' && val.charAt(len - 1) == '\'') || (val.charAt(0) == '\"' && val.charAt(len - 1) == '\"'))){
				val = val.substring(1, len - 1);
			}

			map.put(item.key, Utils.Translate(val));
		}

		return map;
	}
}